/* PR c/102989 */
/* { dg-do run { target bitint } } */
/* { dg-options "-std=c23 -pedantic-errors" } */
/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */

#if __BITINT_MAXWIDTH__ >= 135
struct S135 { unsigned _BitInt(135) c, d; } s135[2];
unsigned _BitInt(135) v135;

__attribute__((noipa)) void
test135 (unsigned _BitInt(135) a, unsigned _BitInt(135) *b, int i, int *j)
{
  s135[0].c = a + (b[0] - b[i + 1]) + (b[2] << 7) - (b[3] + 42);
  s135[i].d = (a | (b[4] & b[5])) ^ b[6 + i];
  j[0] = s135[1 - i].d == 0;
  j[1] = b[7] == 41066216447087484049564603714591595841626uwb;
  if (b[8] != (b[9] << 25))
    b[10] = -1;
  v135 = b[11] + 42953568208323086417402824216666875252142uwb;
  b[12] = ~b[13];
  b[14] = -b[i + 13];
}

__attribute__((noipa)) void
check135 (void)
{
  static unsigned _BitInt(135) b[] = {
    8463654185126215364154304684888703364649uwb,
    13658636853650784933344312223424772115066uwb,
    18390507727765446703890200284988625150777uwb,
    39889350586873865111357164950780819590308uwb,
    33022475220127125972541408550886872946157uwb,
    11333291582071369827887273502665555805026uwb,
    3902203683482045798302423557190uwb,
    41066216447087484049564603714591595841626uwb,
    16784965627356370497109555127280042979599uwb,
    7643716056186238617582842123439581326016uwb,
    19836147734043931654921333860970539101678uwb,
    12432610573803574406235637996243202359232uwb,
    21082105046139319624321070809125021432333uwb,
    4451745762839330307043673589610uwb,
    0uwb
  };
  int j[2];
  unsigned _BitInt(135) a
    = 31187320352518101815881924683645645881322uwb;
  s135[1].d = 11834999377838661704814127001992153922683uwb;
  test135 (a, b, 0, &j[0]);
  if (s135[0].c != 31612399059450309097747051855757230322507uwb
      || s135[0].d != 42086989921663500164906031508060611173292uwb
      || j[0] != 0
      || j[1] != 1
      || v135 != 11830035816246537500326512461643746545006uwb
      || b[10] != (unsigned _BitInt(135)) -1wb
      || b[12] != 43556142961428377560472619444222657476757uwb
      || b[14] != 43556142961428377560472619444222657476758uwb)
    __builtin_abort ();
  static unsigned _BitInt(135) c[] = {
    1551285959809994210151290388254024769929uwb,
    9215997233892929635003694907344971975862uwb,
    39194975204437258458997572112485704553492uwb,
    30855703323230132032090704189294312024903uwb,
    21369469779496743410402906224964849075932uwb,
    14841665908022079679702934181971886622844uwb,
    19630534803796254511661738870561125391241uwb,
    43019675483091641860333234580998356788381uwb,
    39970634580048249544562112517644333613056uwb,
    1191217737795360372798505798508058uwb,
    37946572714876419093215575675176896482623uwb,
    4232750244223021640360996638731476646770uwb,
    4052758609491127849063467754379555742566uwb,
    39722275064055273051470447567883559006300uwb,
    0uwb
  };
  a = 24657112304265243122405775577311943535949uwb;
  s135[1].d = 0;
  test135 (a, c, 0, &j[0]);
  if (s135[0].c != 37693225764587199559589625622735125586095uwb
      || s135[0].d != 28346681648428908942498835305586873104084uwb
      || j[0] != 1
      || j[1] != 0
      || v135 != 3630175486665984734451871104132020832544uwb
      || c[10] != 37946572714876419093215575675176896482623uwb
      || c[12] != 3833867901824850271841502183382772060067uwb
      || c[14] != 3833867901824850271841502183382772060068uwb)
    __builtin_abort ();
}
#endif

#if __BITINT_MAXWIDTH__ >= 192
struct S192 { unsigned _BitInt(192) c, d; } s192[2];
unsigned _BitInt(192) v192;

__attribute__((noipa)) void
test192 (unsigned _BitInt(192) a, unsigned _BitInt(192) *b, int i, int *j)
{
  s192[0].c = a + (b[0] - b[i + 1]) + (b[2] << 7) - (b[3] + 42);
  s192[i].d = (a | (b[4] & b[5])) ^ b[6 + i];
  j[0] = s192[1 - i].d == (unsigned _BitInt(192)) -1;
  j[1] = (b[7] - b[6]) == 255187001951392025884741936737034599050205342889367592965uwb;
  if (b[8] != (b[9] << 25))
    b[10] = -1;
  v192 = b[11] + 2163738967454769289750177070635481073128375537642482578981uwb;
  b[12] = ~b[13];
  b[14] = -b[i + 13];
}

__attribute__((noipa)) void
check192 (void)
{
  static unsigned _BitInt(192) b[] = {
    3228866936540682691868394180939247213045089209876303887643uwb,
    3908758529346495655434258047388434965374712986050611884354uwb,
    1851532482363341717513713701170081412289228794495066903175uwb,
    5975293786133775194483789296663647337052708600272963495919uwb,
    2820057475559560607299380550839942093606275933232105346229uwb,
    5362817792426405848910790868188776921236918437924704229050uwb,
    979877290520863780830672004560233786791511895586353138705uwb,
    1235064292472255806715413941297268385841717238475720731670uwb,
    5829209170873343132786365572649959801760991694267006189140uwb,
    3298265737098071024465207026022448799296008756143231498035uwb,
    940670103332613157768642186014034108249816638700548072517uwb,
    2237128221585286673265910175884786455449703050136766895084uwb,
    5343797638430338971087457378870861887867024738000778783665uwb,
    2529390643742992876667887597532819348219532837015437654241uwb,
    0uwb
  };
  int j[2];
  unsigned _BitInt(192) a
    = 2618661874473674031833709426402867675358124955059180091771uwb;
  s192[1].d = 3240880288967057869631914892069482190385384187140994012855uwb;
  test192 (a, b, 0, &j[0]);
  if (s192[0].c != 706870028734637453615201354376795963209926828811195228347uwb
      || s192[0].d != 2285738979037264170090375369163685923831632419516523901418uwb
      || j[0] != 0
      || j[1] != 1
      || v192 != 4400867189040055963016087246520267528578078587779249474065uwb
      || b[10] != 6277101735386680763835789423207666416102355444464034512895uwb
      || b[12] != 3747711091643687887167901825674847067882822607448596858654uwb
      || b[14] != 3747711091643687887167901825674847067882822607448596858655uwb)
    __builtin_abort ();
  static unsigned _BitInt(192) c[] = {
    5056545299578942817419004982927444283363838129353580295745uwb,
    3531417693480247808623806953213145420554761387079781845903uwb,
    344995382910742860278210827312297947555943126346350032667uwb,
    1665878021517466104406447387862080652541968946313097848513uwb,
    3702336991937894056852499403052128743722086447309795810459uwb,
    3047176269106908247893091430981158526415914935872745232818uwb,
    5837808927599143324365016946161962633699774149391236391641uwb,
    616230573526655023040079960385747061734409792273035529358uwb,
    4899745987387470009167824739532983626288828402149586108416uwb,
    146023809533937871729368708715825784989858520095038uwb,
    1818078651877174878773673167465776979421635253130676590402uwb,
    708253875247724856385503140762213862078700660051492170198uwb,
    1918646725296468312732447651696775312079697668357127231420uwb,
    3407896467949241097221562008023866460487016701943186636216uwb,
    0uwb
  };
  a = 4334425031127766761089651540568319387961460796342206894467uwb;
  s192[1].d = -1;
  test192 (a, c, 0, &j[0]);
  if (s192[0].c != 4413371480577316434238862115941009972672800653387470086858uwb
      || s192[0].d != 2226914616394806622299956064802345362767073196810043931466uwb
      || j[0] != 1
      || j[1] != 0
      || v192 != 2871992842702494146135680211397694935207076197693974749179uwb
      || c[10] != 1818078651877174878773673167465776979421635253130676590402uwb
      || c[12] != 2869205267437439666614227415183799955615338742520847876679uwb
      || c[14] != 2869205267437439666614227415183799955615338742520847876680uwb)
    __builtin_abort ();
}
#endif

#if __BITINT_MAXWIDTH__ >= 255
struct S255 { unsigned _BitInt(255) c, d; } s255[2];
unsigned _BitInt(255) v255;

__attribute__((noipa)) void
test255 (unsigned _BitInt(255) a, unsigned _BitInt(255) *b, int i, int *j)
{
  s255[0].c = a + (b[0] - b[i + 1]) + (b[2] << 12) - (b[3] + 42);
  s255[i].d = (a | (b[4] & b[5])) ^ b[6 + i];
  j[0] = s255[1 - i].d == 255187001951392025884741936737034599050205342889367592965uwb;
  j[1] = (b[7] - b[6]) == 35079516404010817908112229771536766101092256322770268596592519563335917296247uwb;
  if (b[8] != (b[9] << 42))
    b[10] = -1;
  v255 = b[11] + 9589198606702369375056479928174941699714421508271337355764754830579779054882uwb;
  b[12] = ~b[13];
  b[14] = -b[i + 13];
}

__attribute__((noipa)) void
check255 (void)
{
  static unsigned _BitInt(255) b[] = {
    3861714047960214860503769476754636024261469188339866686856553775336008577557uwb,
    51175255900783946984470019707544472774211315503709121319713624735134204561369uwb,
    17345603833958095509660462595097262634109622426516669177449315775424443341657uwb,
    42823701374562019745772585881781652129981403461863690469883912594099541433080uwb,
    51319674321995616727877469124404951867658380853042706770000900262120757183208uwb,
    52906636245432908656398520278306560145122955700637871390327152110192649720972uwb,
    17358815113825560149028333410813032121665286465083593038209986169266901681646uwb,
    52438331517836378057140563182349798222757542787853861634802505732602818977893uwb,
    2788004462553513100609800852000190119799062917794460119684836482863393638874uwb,
    1371934028037182110859712841210549299053627214483532073119322938817156900802uwb,
    27446425677305660137811201333992510946884519570968084003836788091973600281223uwb,
    26953886320773144921523720569352939441073773759009802807981124464100414571230uwb,
    4136701104931368824349366292837727313467036617036788061778000290667287672703uwb,
    16284209316703094594160217903483772091891615489911326105642136930965810318850uwb,
    0uwb
  };
  int j[2];
  unsigned _BitInt(255) a
    = 43671209527014657031076032832534182807479171149570250544322965577348390656271uwb;
  s255[1].d = 255187001951392025884741936737034599050205342889367592965uwb;
  test255 (a, b, 0, &j[0]);
  if (s255[0].c != 20576567717160318081578175912662929186060780346948500086480401311222111385641uwb
      || s255[0].d != 39177534735914878791230670587295539597881897796949856541813587771063479852129uwb
      || j[0] != 1
      || j[1] != 1
      || v255 != 36543084927475514296580200497527881140788195267281140163745879294680193626112uwb
      || b[10] != 57896044618658097711785492504343953926634992332820282019728792003956564819967uwb
      || b[12] != 41611835301955003117625274600860181834743376842908955914086655072990754501117uwb
      || b[14] != 41611835301955003117625274600860181834743376842908955914086655072990754501118uwb)
    __builtin_abort ();
  static unsigned _BitInt(255) c[] = {
    7981769630282326956199854914771456697123750044016665635797085873395082876412uwb,
    53388853971156757275720047407967538568298021437528793620790412040317130403689uwb,
    26701828432251973964608431737798795253412436987727543352462415534788835630812uwb,
    5440780860746561756714149436754163126067503344036226572647314943619048388690uwb,
    33986332817169953208946609849689345925961381637863140695485139248791268070886uwb,
    4100939267210968649446715463008507186522717252282546996073651959494281461390uwb,
    51781097727624204498405281053756240112648760803686514440326944560679935060229uwb,
    39871871446047940023148355012724181415135167919226806605949531421611900671463uwb,
    22669501989113495379481452050938385508947296877470428714787872701608093548544uwb,
    5154447987732395490520832948036146605988346181554886405771838486uwb,
    22291959629998533921508247788279156576466986919969930954212934913917085206989uwb,
    1961549937179049997528355604457213261448618818592679790977249627688612403787uwb,
    41836060567948575115843842705609341074148894754978250388257622994608010108015uwb,
    21250627322648087754897420116830444064785267321586891615233932456372363316960uwb,
    0uwb
  };
  a = 4334425031127766761089651540568319387961460796342206894467uwb;
  s255[1].d = 41611835301955003117625274600860181834743376842908955914086655072990754501117uwb;
  test255 (a, c, 0, &j[0]);
  if (s255[0].c != 12109153275975887113226632923657866254324254170345083268415546710877474684826uwb
      || s255[0].d != 55850175013735185955402882706756822737483750660992935334535260602616242125954uwb
      || j[0] != 0
      || j[1] != 0
      || v255 != 11550748543881419372584835532632154961163040326864017146742004458268391458669uwb
      || c[10] != 22291959629998533921508247788279156576466986919969930954212934913917085206989uwb
      || c[12] != 36645417296010009956888072387513509861849725011233390404494859547584201503007uwb
      || c[14] != 36645417296010009956888072387513509861849725011233390404494859547584201503008uwb)
    __builtin_abort ();
}
#endif

#if __BITINT_MAXWIDTH__ >= 256
struct S256 { unsigned _BitInt(256) c, d; } s256[2];
unsigned _BitInt(256) v256;

__attribute__((noipa)) void
test256 (unsigned _BitInt(256) a, unsigned _BitInt(256) *b, int i, int *j)
{
  s256[0].c = a + (b[0] - b[i + 1]) + (b[2] << 15) - (b[3] - 135wb);
  s256[i].d = (a | (b[4] & b[5])) ^ b[6 + i];
  j[0] = s256[1 - i].d == 53206656141818470791424256353006269277597513345110510288076840335108990485400uwb;
  j[1] = (b[7] - b[6]) == 100099038883167575868168369054142100716577408309486879759875338591874183239821uwb;
  if (b[8] != (b[9] << 63))
    b[10] = -1;
  v256 = b[11] + 105302399496355811946682562261964785380738245520086820947909580844925217183297uwb;
  b[12] = ~b[13];
  b[14] = -b[i + 13];
}

__attribute__((noipa)) void
check256 (void)
{
  static unsigned _BitInt(256) b[] = {
    32009310487117026679674626072407603367594653139936438287667930528262453801915uwb,
    65176902468824044453790267089157089693737812535360753024943201863160377679656uwb,
    82344070090465165315955757521075336622529332575448066816076316414765425718982uwb,
    1700965766421539490938858830624234600098958435316757520284868641071726580981uwb,
    43634292917714777985622413899887802700784049405471615230478960221105984199159uwb,
    100631692904819207373422601372327472587552135350288379476708675217470156851657uwb,
    110129860579524893207321038633598210672223454232798756477691416433717017519769uwb,
    22023582511300831410026311598353795806875331462942548421790016502461571529072uwb,
    40138510211986216232290944684699787930583492725766883760868504701674647977984uwb,
    4351825997216706075548423101456944800498099170105917024323uwb,
    169752993639582224244050634348149779190985669780902142577260914458554153598uwb,
    32145284966541819913159374355840318160537667734553997019437196071417771295134uwb,
    54664388217936175028491213294153178079954834597579823229832063212225827892844uwb,
    20191860868728322538097431032697551245493230687142770900578302601765403775815uwb,
    0uwb
  };
  int j[2];
  unsigned _BitInt(256) a
    = 35032284611123531672148181265368654016291603806765316452453041084857012399819uwb;
  s256[1].d = 18495552704607464237917826961539803493777535452633922395016139213747075459320uwb;
  test256 (a, b, 0, &j[0]);
  if (s256[0].c != 63389043283546287594263459568996583234036639501854425943006627750610451754736uwb
      || s256[0].d != 85940937558229637292496709413287085767649546821453763197795096316568198990162uwb
      || j[0] != 0
      || j[1] != 0
      || v256 != 21655595225581436436270951609117195688005928589000253927889192908429858838495uwb
      || b[10] != 169752993639582224244050634348149779190985669780902142577260914458554153598uwb
      || b[12] != 95600228368587872885473553975990356607776753978497793138879281406147725864120uwb
      || b[14] != 95600228368587872885473553975990356607776753978497793138879281406147725864121uwb)
    __builtin_abort ();
  static unsigned _BitInt(256) c[] = {
    32343204662160194495085563951007642761735079004830363200819846414562640245919uwb,
    24084137699661809462548106377371635219349193031343667516905836190779613998386uwb,
    101379688603662938586655900818791548427393428573101695287405037352360497544008uwb,
    49527008749469396581891560939525147311301744659706134394761856095820111704400uwb,
    78611633605884634807198913241948438916640856307470257529328762903676002499180uwb,
    7725329946357185150163578923822973618563365182619444740561512924522337085644uwb,
    87230734821522736453376619836617027268082314423737558813724810260551555679101uwb,
    71537684467374116897974003882071220131389738067583874534142564844512609278986uwb,
    52523168514171623670932664104908233302972408272520282168521737371661091576905uwb,
    55534995177165851478287456502449363262630885721301994816018615193922251275498uwb,
    36185028875353330724983116385242607835574307465276274632872421166901316306305uwb,
    105156498492189914423239302852802412965634513221765962480547101568217183385322uwb,
    107291868576624602610288559845636897859595852848306710447908839132037475007641uwb,
    31763533437617266501468240129359520348601211969709950732394000355828663205766uwb,
    0uwb
  };
  a = 9837521119254571559208641097198297536765546083418356216057243384350911670458uwb;
  s256[1].d = 53206656141818470791424256353006269277597513345110510288076840335108990485400uwb;
  test256 (a, c, 0, &j[0]);
  if (s256[0].c != 18957614795124660722423653645379624133127098231408367194845756641321108143966uwb
      || s256[0].d != 96521194298766978603491920349693757511095007817895085416680901426339418123139uwb
      || j[0] != 1
      || j[1] != 1
      || v256 != 94666808751229530946350880106079290493102774076212219388999098405229270928683uwb
      || c[10] != 115792089237316195423570985008687907853269984665640564039457584007913129639935uwb
      || c[12] != 84028555799698928922102744879328387504668772695930613307063583652084466434169uwb
      || c[14] != 84028555799698928922102744879328387504668772695930613307063583652084466434170uwb)
    __builtin_abort ();
}
#endif

int
main ()
{
#if __BITINT_MAXWIDTH__ >= 135
  check135 ();
#endif
#if __BITINT_MAXWIDTH__ >= 192
  check192 ();
#endif
#if __BITINT_MAXWIDTH__ >= 255
  check255 ();
#endif
#if __BITINT_MAXWIDTH__ >= 256
  check256 ();
#endif
  return 0;
}
